function debounce(fn, delay, immediate = false, resultCallback) {
  // 1.定义一个定时器，保存上一次的定时器
  let timer = null;
  let isInvoke = false;

  // 2.真正执行的函数
  const _debounce = function(...args) {
    return new Promise((resolve, reject) => {
      // 把上一次取消
      if(timer) clearTimeout(timer);
      // 判断是否需要立即执行
      if(immediate && !isInvoke) {
        const result = fn.apply(this, args);
        if(resultCallback) resultCallback(result);
        resolve(result);
        isInvoke = true;
      } else {
        // 延迟执行
        timer = setTimeout(() => {
          // 外部传入的真正函数
          // 解决this和event的指向
          const result = fn.apply(this, args);
          if(resultCallback) resultCallback(result);
          resolve(result);
          isInvoke = false;
          timer = null;
        }, delay)
      }
    })
  }

  // 封装取消功能
  _debounce.cancel = function() {
    if(timer) clearTimeout(timer);
    timer = null;
    isInvoke = false;
  }

  return _debounce;
}

